package com.cai310.lottery.entity.user;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Lob;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import javax.persistence.Version;

import org.apache.commons.lang.StringUtils;
import org.hibernate.annotations.Parameter;
import org.hibernate.annotations.Type;
import org.hibernate.type.EnumType;

import com.cai310.entity.CreateMarkable;
import com.cai310.entity.IdEntity;
import com.cai310.entity.UpdateMarkable;
import com.cai310.lottery.common.AgentLotteryType;
import com.cai310.lottery.common.DrawingOrderState;
import com.cai310.lottery.common.Lottery;
import com.cai310.lottery.exception.DataException;
import com.cai310.lottery.support.Item;
import com.cai310.lottery.support.agent.RebateLimitUpdate;
import com.cai310.lottery.support.agent.UserRebateLimit;
import com.cai310.lottery.support.agent.UserRebateLimitList;
import com.cai310.lottery.support.jclq.JclqCompoundContent;
import com.cai310.lottery.support.jclq.JclqMatchItem;
import com.cai310.lottery.support.jclq.PassType;
import com.cai310.lottery.support.jclq.PlayType;
import com.cai310.lottery.support.jczq.JczqMatchItem;
import com.cai310.utils.JsonUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

@Entity
@Table(name = com.cai310.lottery.Constant.LOTTERY_TABLE_PREFIX + "AGENT_REBATE")
public class UserRebate extends IdEntity implements CreateMarkable, UpdateMarkable, Serializable {
	private static final long serialVersionUID = 6420283302235215768L;
	// Fields
	// 充值，提现，投注，返点，撤单，追号
	private Long userId;
	private String userName;
	private String realName;
	/** 用户的返点*/
	private Double rebate;
	/**
	 * 彩票类型
	 * 
	 * @see com.cai310.lottery.common.AgentLotteryType
	 */
	private AgentLotteryType agentLotteryType;
	/** 创建时间 */
	private Date createTime;

	/** 最后更新时间 */
	private Date lastModifyTime;
	
	/** 版本号,用于实现乐观锁 */
	private Integer version;
	private Long groupCount;
	private Long agentCount;
	private String limitJson;
	
	// Constructors

	/** default constructor */
	public UserRebate() {
	}
	@Transient
	public List<UserRebateLimit> getlimitJsonObj() {
		if (StringUtils.isBlank(this.getLimitJson()))
			return null;
		@SuppressWarnings("rawtypes")
		Map classMap = new HashMap();
		classMap.put("items", UserRebateLimit.class);
		UserRebateLimitList userRebateLimitList = JsonUtil.getObject4JsonString(this.getLimitJson(), UserRebateLimitList.class, classMap);
		
		return userRebateLimitList.getItems();
	}
	@Transient
	public void setlimitNumber(List<UserRebateLimit> userRebateLimitList) {
		List<UserRebateLimit> oldUSerRebateLimit = this.getlimitJsonObj();
		UserRebateLimitList limitList = new UserRebateLimitList();
		if(null==oldUSerRebateLimit||oldUSerRebateLimit.isEmpty()){
			////还没有设置返点
			limitList.setItems(userRebateLimitList);
			this.setLimitJson(JsonUtil.getJsonString4JavaPOJO(limitList));
		}else{
			List<UserRebateLimit> newRebateLimit = Lists.newArrayList();
            for (UserRebateLimit oldUserRebateLimit : oldUSerRebateLimit) {
            	for (UserRebateLimit userRebateLimit : userRebateLimitList) {
					if(userRebateLimit.getRebate()==oldUserRebateLimit.getRebate()){
						oldUserRebateLimit.setLimitNumber(userRebateLimit.getGroupNumber());
						newRebateLimit.add(oldUserRebateLimit);
					}
				}
			}
            limitList.setItems(newRebateLimit);
			this.setLimitJson(JsonUtil.getJsonString4JavaPOJO(limitList));
		}
	}
	@Transient
	public void updateLimitNumber(List<UserRebateLimit> userRebateLimitList) {
		List<UserRebateLimit> oldUSerRebateLimit = this.getlimitJsonObj();
		UserRebateLimitList limitList = new UserRebateLimitList();
		if(null==oldUSerRebateLimit||oldUSerRebateLimit.isEmpty()){
			////还没有设置返点
			limitList.setItems(userRebateLimitList);
			this.setLimitJson(JsonUtil.getJsonString4JavaPOJO(limitList));
		}else{
			List<UserRebateLimit> newRebateLimit = Lists.newArrayList();
			Map<String,UserRebateLimit> oldMap = Maps.newHashMap();
			for (UserRebateLimit oldUserRebateLimit : oldUSerRebateLimit) {
				oldMap.put(oldUserRebateLimit.getRebate(), oldUserRebateLimit);
			}
            for (UserRebateLimit userRebateLimit : userRebateLimitList) {
            	UserRebateLimit oldUserRebateLimit = oldMap.get(userRebateLimit.getRebate());
                if(null!=oldUserRebateLimit){
                	oldUserRebateLimit.setLimitNumber(userRebateLimit.getGroupNumber());
                	oldMap.put(userRebateLimit.getRebate(),oldUserRebateLimit);
                }else{
                	oldMap.put(userRebateLimit.getRebate(),userRebateLimit);
                }
			}
            newRebateLimit.addAll(oldMap.values());
            limitList.setItems(newRebateLimit);
			this.setLimitJson(JsonUtil.getJsonString4JavaPOJO(limitList));
		}
	}
	/*
	 * 直接设置下属的已用配额
	 */
	@Transient
	public void updateMyAgentGroupNumber(List<UserRebateLimit> updateRebateLimitList) throws DataException {
		List<UserRebateLimit> myRebateLimitList = this.getlimitJsonObj();
		UserRebateLimitList limitList = new UserRebateLimitList();
		if(null==myRebateLimitList||myRebateLimitList.isEmpty()){
			////还没有设置返点
			throw new DataException("账户配额异常");
		}else{
			List<UserRebateLimit> newRebateLimitList = Lists.newArrayList();
            for (UserRebateLimit myRebateLimit : myRebateLimitList) {
            	for (UserRebateLimit updateRebateLimit : updateRebateLimitList) {
					if(myRebateLimit.getRebate().equals(updateRebateLimit.getRebate())){
						if(myRebateLimit.findLeftNumber()<updateRebateLimit.getLimitNumber())throw new DataException("账户配额少于目标用户配额");
						myRebateLimit.setGroupNumber(myRebateLimit.getGroupNumber()+updateRebateLimit.getLimitNumber());
					}
				}
            	newRebateLimitList.add(myRebateLimit);
			}
            limitList.setItems(newRebateLimitList);
			this.setLimitJson(JsonUtil.getJsonString4JavaPOJO(limitList));
		}
	}
	/*
	 * 修改设置下属的配额
	 */
	@Transient
	public void updateMyLimitNumber(List<RebateLimitUpdate> rebateLimitUpdateList) throws DataException {
		List<UserRebateLimit> myRebateLimitList = this.getlimitJsonObj();
		UserRebateLimitList limitList = new UserRebateLimitList();
		if(null==myRebateLimitList||myRebateLimitList.isEmpty()){
			////还没有设置返点
			throw new DataException("账户配额异常");
		}else{
			List<UserRebateLimit> newRebateLimitList = Lists.newArrayList();
            for (UserRebateLimit myRebateLimit : myRebateLimitList) {
            	for (RebateLimitUpdate rebateLimitUpdate : rebateLimitUpdateList) {
					if(myRebateLimit.getRebate().equals(rebateLimitUpdate.getRebate())){
						if(rebateLimitUpdate.getUpdateNumber()<0){
							//当操作配额小于0的时候。需要减少配额。要判断当前配额和已用配额
							if(myRebateLimit.getLimitNumber()-Math.abs(rebateLimitUpdate.getUpdateNumber())<myRebateLimit.getGroupNumber())
								throw new DataException("账户配额少于用户已用配额");
							myRebateLimit.setLimitNumber(myRebateLimit.getLimitNumber()-Math.abs(rebateLimitUpdate.getUpdateNumber()));
						}else if(rebateLimitUpdate.getUpdateNumber()>0){
							myRebateLimit.setLimitNumber(myRebateLimit.getLimitNumber()+Math.abs(rebateLimitUpdate.getUpdateNumber()));
						}
					}
				}
            	newRebateLimitList.add(myRebateLimit);
			}
            limitList.setItems(newRebateLimitList);
			this.setLimitJson(JsonUtil.getJsonString4JavaPOJO(limitList));
		}
	}
	/*
	 * 修改设置下属的已用配额
	 */
	@Transient
	public void updateMyGroupNumber(List<RebateLimitUpdate> rebateLimitUpdateList) throws DataException {
		List<UserRebateLimit> myRebateLimitList = this.getlimitJsonObj();
		UserRebateLimitList limitList = new UserRebateLimitList();
		if(null==myRebateLimitList||myRebateLimitList.isEmpty()){
			////还没有设置返点
			throw new DataException("账户配额异常");
		}else{
			List<UserRebateLimit> newRebateLimitList = Lists.newArrayList();
            for (UserRebateLimit myRebateLimit : myRebateLimitList) {
            	for (RebateLimitUpdate rebateLimitUpdate : rebateLimitUpdateList) {
					if(myRebateLimit.getRebate().equals(rebateLimitUpdate.getRebate())){
						if(rebateLimitUpdate.getUpdateNumber()<0){
							myRebateLimit.setGroupNumber(myRebateLimit.getGroupNumber()-Math.abs(rebateLimitUpdate.getUpdateNumber()));
						}else if(rebateLimitUpdate.getUpdateNumber()>0){
							//当操作数小于0的时候。需要增加配额。要判断当前配额和已用配额
							if(myRebateLimit.getGroupNumber()+Math.abs(rebateLimitUpdate.getUpdateNumber())>myRebateLimit.getLimitNumber())
								throw new DataException("账户配额少于用户已用配额");
							myRebateLimit.setGroupNumber(myRebateLimit.getGroupNumber()+Math.abs(rebateLimitUpdate.getUpdateNumber()));
						}
					}
				}
            	newRebateLimitList.add(myRebateLimit);
			}
            limitList.setItems(newRebateLimitList);
			this.setLimitJson(JsonUtil.getJsonString4JavaPOJO(limitList));
		}
	}
	/**
	 * @return the createTime
	 */
	@Temporal(TemporalType.TIMESTAMP)
	@Column(nullable = false, updatable = false)
	public Date getCreateTime() {
		return createTime;
	}

	/**
	 * @param createTime the createTime to set
	 */
	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}
	@Temporal(TemporalType.TIMESTAMP)
	@Column(insertable = false)
	public Date getLastModifyTime() {
		return lastModifyTime;
	}

	public void setLastModifyTime(Date lastModifyTime) {
		this.lastModifyTime = lastModifyTime;
	}
	/**
	 * @return {@link #version}
	 */
	@Version
	@Column(nullable = false)
	public Integer getVersion() {
		return version;
	}

	/**
	 * @param version the version to set
	 */
	public void setVersion(Integer version) {
		this.version = version;
	}
	@Column
	public Long getUserId() {
		return userId;
	}

	public void setUserId(Long userId) {
		this.userId = userId;
	}
	@Column
	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}
	@Column
	public String getRealName() {
		return realName;
	}

	public void setRealName(String realName) {
		this.realName = realName;
	}

	@Column
	public Double getRebate() {
		return rebate;
	}

	public void setRebate(Double rebate) {
		this.rebate = rebate;
	}
	/**
	 * 彩票类型
	 * 
	 * @return {@link #lotteryType}
	 * @see com.cai310.lottery.common.Lottery
	 */
	@Type(type = "org.hibernate.type.EnumType", parameters = {
			@Parameter(name = EnumType.ENUM, value = "com.cai310.lottery.common.AgentLotteryType"),
			@Parameter(name = EnumType.TYPE, value = Lottery.SQL_TYPE) })
	@Column(nullable = false, updatable = false)
	public AgentLotteryType getAgentLotteryType() {
		return agentLotteryType;
	}

	/**
	 * 设置彩票类型
	 * 
	 * @param lotteryType {@link #lotteryType}
	 * @see com.cai310.lottery.common.Lottery
	 */
	public void setAgentLotteryType(AgentLotteryType agentLotteryType) {
		this.agentLotteryType = agentLotteryType;
	}

	@Column
	public Long getGroupCount() {
		return groupCount;
	}

	public void setGroupCount(Long groupCount) {
		this.groupCount = groupCount;
	}
	@Column
	public Long getAgentCount() {
		return agentCount;
	}

	public void setAgentCount(Long agentCount) {
		this.agentCount = agentCount;
	}
	@Lob
	@Column
	public String getLimitJson() {
		return limitJson;
	}

	public void setLimitJson(String limitJson) {
		this.limitJson = limitJson;
	}


}